from typing import Union, Any
from dataclasses import dataclass
from django.db.models import Count, Avg, Case, When, Q
from django.db.models import IntegerField

from . import models


@dataclass
class StatisticsOfHumanActionsData:
    """ Описание структуры данных 'Статистика поступков человека' """

    name: str
    surname: str
    number_of_positive_actions: int
    number_of_neutral_actions: int
    number_of_negative_actions: int
    average_evaluation_of_action: Union[int, float]


def get_statistics_of_human_actions(
    human_id: int
) -> StatisticsOfHumanActionsData:
    """ Получаем статистику поступков человека """

    statistics = models.Human.objects.filter(
        id=human_id
    ).values(
        'name', 'surname'
    ).annotate(
        number_of_positive_actions=Count(
            Case(
                When(actions__evaluation__gt=5, then=1),
                output_field=IntegerField()
            )
        ),
        number_of_neutral_actions=Count(
            Case(
                When(actions__evaluation=5, then=1),
                output_field=IntegerField()
            )
        ),
        number_of_negative_actions=Count(
            Case(
                When(actions__evaluation__lt=5, then=1),
                output_field=IntegerField()
            )
        ),
        average_evaluation_of_action=Avg('actions__evaluation')
    )[0]

    return StatisticsOfHumanActionsData(**statistics)


def get_statistics_on_married_people(city_name: str) -> Any:
    """ Получаем статистику по людям находящимся в браке """

    return models.Human.objects.filter(
        Q(additional_data__is_married=True) &
        Q(additional_data__is_unemployed__isnull=True) &
        Q(addresses__city__in=[city_name]) &
        Q(actions__evaluation__gt=6),
    ).distinct().count()
